#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include "writer.h"

using namespace std;

//------------------------------------------------------------------------------
// Add primitive variables defined at vertices
//------------------------------------------------------------------------------
void Writer::attach_vertex_data (vector<PrimVar>& data)
{
   assert (!has_vertex_primitive);
   vertex_primitive = &data;
   has_vertex_primitive = true;
}

//------------------------------------------------------------------------------
// Write data to vtk file
//------------------------------------------------------------------------------
void Writer::output_vtk (string filename)
{
   assert (has_vertex_primitive);

   ofstream vtk;
   vtk.open (filename.c_str());

   vtk << "# vtk DataFile Version 3.0" << endl;
   vtk << "gmm3d solution file" << endl;
   vtk << "ASCII" << endl;
   vtk << "DATASET UNSTRUCTURED_GRID" << endl;
   vtk << "POINTS  " << grid->n_vertex << "  float" << endl;

   for(unsigned int i=0; i<grid->n_vertex; ++i)
      vtk << grid->vertex[i].coord.x << " " 
          << grid->vertex[i].coord.y << " " 
          << grid->vertex[i].coord.z << endl;

   vtk << "CELLS  " << grid->n_cell << " " << 5 * grid->n_cell << endl;
   for(unsigned int i=0; i<grid->n_cell; ++i)
      vtk << 4 << "  " 
          << grid->cell[i].vertex[0] << " "
          << grid->cell[i].vertex[1] << " "
          << grid->cell[i].vertex[2] << " "
          << grid->cell[i].vertex[3] << endl;

   vtk << "CELL_TYPES  " << grid->n_cell << endl;
   for(unsigned int i=0; i<grid->n_cell; ++i)
      vtk << 10 << endl;

   // Write vertex data
   vtk << "POINT_DATA  " << grid->n_vertex << endl;

   // If vertex primitive data is available, write to file
   if (has_vertex_primitive)
   {
      vtk << "SCALARS density float 1" << endl;
      vtk << "LOOKUP_TABLE default" << endl;
      for(unsigned int i=0; i<grid->n_vertex; ++i)
         vtk << (*vertex_primitive)[i].density << endl;

      vtk << "SCALARS pressure float 1" << endl;
      vtk << "LOOKUP_TABLE default" << endl;
      for(unsigned int i=0; i<grid->n_vertex; ++i)
         vtk << (*vertex_primitive)[i].pressure << endl;

      vtk << "VECTORS velocity float" << endl;
      for(unsigned int i=0; i<grid->n_vertex; ++i)
         vtk << (*vertex_primitive)[i].velocity.x << "  "
             << (*vertex_primitive)[i].velocity.y << "  "
             << (*vertex_primitive)[i].velocity.z
             << endl;
   }

   vtk.close ();
}

//------------------------------------------------------------------------------
// Write solution for restarting
//------------------------------------------------------------------------------
void Writer::output_restart ()
{
   assert (has_vertex_primitive);

   cout << "Saving restart file flo3d.sol\n";

   ofstream fo;
   fo.open ("flo3d.sol");
   assert (fo.is_open());

   for(unsigned int i=0; i<grid->n_vertex; ++i)
      fo << scientific
         << (*vertex_primitive)[i].density << "  "
         << (*vertex_primitive)[i].velocity.x << "  "
         << (*vertex_primitive)[i].velocity.y << "  "
         << (*vertex_primitive)[i].velocity.z << "  "
         << (*vertex_primitive)[i].pressure   << endl;

   fo.close ();
}
